<template>
  <div>
    <el-card class="box-card">
      <template #header>
        <div class="card-header">
          <span>充值管理</span>
          <span class="ml20 f14 fw400 userMon"
            >当前账户余额
            <span class="moneyNum">{{ moneyNum ? moneyNum : '0.00' }}</span>
            元</span
          >
        </div>
      </template>

      <div class="content">
        <div class="item">
          <div class="label font-weight600">账户充值</div>
          <div class="value">支付成功后，刷新页面可查看余额状态</div>
        </div>
        <el-form
          ref="ruleFormRef"
          :model="form"
          :rules="rules"
          label-width="auto"
          class="demo-ruleForm"
          status-icon
        >
          <el-form-item label="充值金额" prop="amout">
            <el-input
              v-model.number="form.amout"
              style="width: 280px; height: 32px"
              placeholder="输入金额"
            />
            <p style="margin-left: 10px">元</p>
          </el-form-item>
          <el-form-item label="支付方式" prop="payType">
            <div style="width: 200px">
              <el-radio-group
                v-model="form.payType"
                @change="handleRadioChange"
              >
                <el-radio :value="1">在线支付 (实时到账)</el-radio>
                <el-radio :value="2">对公转账 (1~2个工作日)</el-radio>
                <!-- 勿删除接口未出 -->
                <el-radio :value="3">我的代收钱包 (实时到账)</el-radio>
              </el-radio-group>
            </div>
          </el-form-item>
          <el-form-item label="付款方式" prop="type" v-if="form.payType !== 1">
            <div
              v-for="(item, index) in payList"
              :key="item.type"
              class="payMoney"
              :class="{
                isNone:
                  (form.payType == 2 && index == 3) ||
                  (form.payType == 3 && [0, 1, 2].includes(index)),
                active: current == item.type,
              }"
              @click="payBtn(item)"
            >
              <img class="pic" :src="item.imgUrl" />
              {{ item.remark }}
              <check class="check" />
              <div :class="current == item.type ? 'bg' : ''"></div>
            </div>

            <!-- 误删接口没出 -->
            <div
              v-if="form.payType == 3"
              style="display: flex; align-items: center"
            >
              <el-tooltip class="box-item" effect="dark" placement="bottom">
                <template #content>
                  支持使用代收钱包中未被提现的余额用于充值。
                  <br />
                  提交成功后，充值全额实时到账并立即扣除代收钱包余额
                  <br />
                </template>
                <img
                  style="width: 20px; height: 20px; margin-left: 10px"
                  src="https://b.gaokaow.cc/question@2x.png"
                  alt=""
                />
              </el-tooltip>
              <div style="margin-left: 10px">
                当前余额为
                <span style="color: red">{{ balance ?? '0.00' }}</span> 元
              </div>
            </div>
          </el-form-item>

          <el-form-item>
            <el-button
              style="margin-left: 80px"
              type="primary"
              class="stylebtn"
              @click="submitForm(ruleFormRef)"
              >提交</el-button
            >
          </el-form-item>
        </el-form>

        <div class="between">
          <div>账户充值记录</div>
          <div>
            <el-date-picker
              @change="getChangeTime"
              type="daterange"
              v-model="form.time"
              range-separator="至"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              :popper-options="{ placement: 'bottom-end' }"
            />
          </div>
        </div>
        <el-table
          :data="tableData"
          stripe
          height="500px"
          style="width: 100%; margin-top: 20px"
          v-loading="loading"
        >
          <el-table-column prop="mobile" label="操作人" />
          <el-table-column prop="create_time" label="操作时间" />
          <el-table-column prop="out_trade_no" label="订单编号" />
          <el-table-column prop="type" label="支付方式" />
          <el-table-column prop="fee" label="充值金额" />
          <el-table-column prop="trade_state" label="状态" />
          <!-- <el-table-column prop="remark" label="备注" /> -->
          <el-table-column prop="remark" label="备注">
            <template #default="scoped">
              <span>{{ scoped.row.remark ?? '-' }}</span>
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template #default="scoped">
              <el-icon
                class="icon"
                @click="UploadCredentialsOpen((row = scoped.row), (type = 2))"
              >
                <Upload v-if="!scoped.row.img" />
                <View v-else />
              </el-icon>
            </template>
          </el-table-column>
        </el-table>
        <div class="right" style="margin-top: 20px">
          <el-pagination
            v-model:current-page="tableConfig.page"
            v-model:page-size="tableConfig.pageSize"
            :page-sizes="[10, 20, 30]"
            layout="total, sizes, prev, pager, next, jumper"
            :total="parseInt(tableConfig.total)"
            @size-change="pagination"
            @current-change="currentChange"
          />
        </div>
      </div>
    </el-card>

    <el-dialog
      custom-class="maskBox"
      v-model="openFile"
      title="上传凭证"
      width="450px"
      :before-close="handleClose"
    >
      <el-form
        style="max-width: 600px"
        label-width="auto"
        class="demo-ruleForm"
        status-icon
      >
        <el-form-item label="订单编号">
          <span class="txt">{{ uploadCredentialsForm.order }}</span>
        </el-form-item>
        <el-form-item label="充值金额">
          <span class="text">{{ uploadCredentialsForm.RechargeMoney }}</span>
          <span class="moneyT">元</span>
        </el-form-item>
        <el-form-item label="转账时间">
          <el-date-picker
            v-model="pay_time"
            type="date"
            placeholder="转帐时间"
          />
        </el-form-item>
        <el-form-item>
          <div class="flexcenter">
            <UploadImg
              :isShowTip="false"
              :limit="1"
              :modelValue="modelValueList"
              @update:modelValue="modelValue"
            />
            <p>
              请确保上传的凭证图片完整清晰，转账金额与订单金额一致我们会在1个工作日内完成处理
            </p>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="openFile = false">取消</el-button>
          <el-button type="primary" @click="saveUploadBtn">确定上传</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
  <Dialog
    custom-class="maskBox"
    v-model="dialogTableVisible"
    :title="title"
    :form="form"
    width="400"
    style="max-height: none"
    @closeIcon="closeIcon"
    v-if="form.payType != 3"
  >
    <template #qr v-if="code_url">
      <p v-if="form.payType == 1 && !showRefresh" class="top">
        {{
          form.payType == 1 && payStatus ? '打开微信扫一扫' : '打开支付宝扫一扫'
        }}
      </p>
      <p v-else-if="form.payType == 2 && !showRefresh" class="top">
        {{ form.type == 1 ? '打开微信扫一扫' : '打开支付宝扫一扫' }}
      </p>
      <!-- <img :src="code_url" :size="200" level="H" style="z-index: 99" /> -->
      <div style="display: flex; justify-content: center">
        <div
          v-if="form.payType == 1"
          style="position: relative; margin: 10px 0"
        >
          <QrcodeGenerator
            :text="!showRefresh ? code_url : 'INVALID'"
            :size="200"
            level="H"
            style="z-index: 99"
            class="overdue"
          />
          <div class="payChange">
            <span @click="alipaySwith">{{
              payStatus ? '切换到支付宝' : '切换到微信'
            }}</span>
            <!-- <span class="wxPay"
              >( {{ payStatus ? '微信支付' : '支付宝支付' }} )</span
            > -->
          </div>
          <div class="model" v-if="showRefresh"></div>
        </div>
        <img
          v-else-if="form.payType == 2 && !showRefresh"
          style="width: 200px; height: 200px"
          :src="code_url"
        />
      </div>
      <p
        class="count"
        v-if="form.payType == 1 && !showRefresh"
        style="font-size: 12px"
      >
        请在&nbsp;{{ minutes }}&nbsp;分&nbsp;{{ seconds }}&nbsp;秒内完成支付
      </p>
      <div v-if="showRefresh" style="text-align: center; font-size: 12px">
        二维码已失效，请
        <span class="refresh" @click="addfee">刷新</span> 重新支付
      </div>
    </template>
    <template
      #bankInfo
      v-if="hasContent(bankInfo) && current == 3 && form.payType == 2"
    >
      <div class="info">
        <el-form status-icon label-width="auto" class="demo-ruleForm">
          <el-form-item label="开户行">
            <span>{{ bankInfo.bank }}</span>
          </el-form-item>
          <el-form-item label="账户名称">
            <span>{{ bankInfo.name }}</span>
          </el-form-item>
          <el-form-item label="账户">
            <span>{{ bankInfo.root }}</span>
          </el-form-item>
          <el-form-item class="cope" @click="copyToClipboard(bankInfo)">
            复制信息
          </el-form-item>
        </el-form>
      </div>
    </template>
    <template #footer v-if="form.payType != 1">
      <div class="dialog-footer">
        <el-button @click="dialogTableVisible = false">关闭</el-button>
        <el-button
          type="primary"
          @click="UploadCredentialsOpen((row = ''), (type = 1))"
        >
          我已转账
        </el-button>
      </div>
    </template>
  </Dialog>
  <!-- 图片预览组件 -->
  <el-image-viewer
    v-if="showPreview"
    :url-list="previewImageList"
    @close="closePreview"
  />
</template>

<script setup>
import { ref, computed, onMounted } from 'vue';
import UploadImg from '@/components/ImageUpload2/index.vue';
import { ElMessage } from 'element-plus';
// 前端生成二维码组件
import QrcodeGenerator from '@/components/QrcodeGenerator/index.vue';
import { hasContent, formatDateYMD } from '@/utils';
import financialMan from '@/modules';
import recharge from '@/modules';
import withdraw from '@/modules';
import Dialog from './dialog.vue';
const { accountBalanceApi } = withdraw;
// 接口api
const { payVerificationApi, alipayApi } = recharge;
const {
  rechargeLog,
  addMoney,
  merchantType,
  commitRechargeApi,
  upVoucherApi,
  collectionAPI,
} = financialMan;
const payStatus = ref(true); //支付方式状态
const title = ref('扫码支付');
const ruleFormRef = ref();
const showPreview = ref(false);
const previewImageList = ref([]);
const openFile = ref(false);
const code_url = ref('');
const pay_time = ref(''); //转账时间
const out_trade_no = ref('');
const dialogTableVisible = ref(false);
const bankInfo = ref({});
const expireTime = ref(null); // 用于存储过期时间
let pollingInterval = null; // 用于存储定时器ID
const paymentStatus = ref(''); //支付状态
const balance = ref(''); //
const moneyNum = ref('');
const loading = ref(false);
const timeLeft = ref(0);
const current = ref('');
const showRefresh = ref(false);
//图片
const modelValueList = ref([]);
const tableConfig = ref({
  page: 1,
  pageSize: 20,
  startTime: '',
  endTime: '',
  total: 0,
});
const form = ref({
  type: null,
  payType: 1,
  amout: null,
  time: '',
});
const uploadCredentialsForm = ref({
  order: '',
  RechargeMoney: '',
  urlImg: '',
});
const tableData = ref([]);
const rules = ref({
  amout: [
    {
      required: true,
      message: '请输入充值金额',
      trigger: 'blur',
    },
    // 自定义验证规则
    {
      validator: (rule, value, callback) => {
        if (value < 0.01) {
          callback(new Error('充值金额必须大于等于100'));
        } else {
          callback(); // 验证通过
        }
      },
    },
  ],
  type: [{ required: true, message: '付款方式' }],
});
const payList = ref([]);
//关闭弹窗按钮
const closeIcon = () => {
  stopPolling();
  getUserMoney(); //更新账户余额
};
//支付方式状态
const handleRadioChange = (val) => {
  form.value.type = '';
  val == 1 ? (form.value.type = '') : val;
  val == 1 ? (title.value = '扫码支付') : title.value;
};

//图片预览关闭
const closePreview = () => {
  previewImageList.value = [];
  showPreview.value = false;
};
//上传凭证API
const getApi = () => {
  const { id } = form.value;
  upVoucherApi({
    img: modelValueList.value,
    id: id,
    pay_time: formatDateYMD(pay_time.value),
  }).then((res) => {
    if (res.code == 20000) {
      ElMessage({
        message: res.msg,
        type: 'success',
      });
      tableDataList();
    }
  });
};
const saveUploadBtn = () => {
  if (modelValueList.value && pay_time.value != '') {
    getApi();
    openFile.value = false;
    form.value.type = '';
    form.value.amout = '';
    pay_time.value = '';
  }
};
//图片上传
const modelValue = (val) => {
  modelValueList.value = val;
};
//上传凭证
const UploadCredentialsOpen = (row, type) => {
  dialogTableVisible.value = false;
  if (type == 1) {
    openFile.value = true;
    getpayApi();
  }
  if (row.img) {
    previewImageList.value.push(row.img);
    showPreview.value = true;
  } else {
    openFile.value = true;
    uploadCredentialsForm.value.order = row.out_trade_no;
    uploadCredentialsForm.value.RechargeMoney = row.fee;
    modelValueList.value = row.img;
    form.value.id = row.id;
    ruleFormRef.value.clearValidate();
  }
};

const handleClose = () => {
  openFile.value = false;
};

const payBtn = (item) => {
  current.value = item.id ? item.id : '';
  form.value.type = '';
  code_url.value = '';
  bankInfo.value = {};
  form.value.type = item.type;

  form.value.type == 1
    ? (title.value = '微信扫码')
    : form.value.type == 2
      ? (title.value = '支付宝扫码')
      : (title.value = '银行汇款转账');
  if (item.type !== 3) {
    code_url.value = item.qrcode;
  } else {
    // 1. 替换单引号为双引号
    item.info = item.info.replace(/'/g, '"'); // 将所有单引号替换为双引号
    // 2. 解析为对象
    try {
      bankInfo.value = JSON.parse(item.info);
    } catch (error) {
      console.log('error:', error);
    }
  }
};
const minutes = computed(() => Math.floor(timeLeft.value / 60000)); // 60000 毫秒为 1 分钟
const seconds = computed(() => Math.floor((timeLeft.value % 60000) / 1000)); // 1000 毫秒为 1 秒
//切换支付
const alipaySwith = () => {
  stopPolling();
  showRefresh.value = false;
  payStatus.value = !payStatus.value;
  moneyAddFn();
};
// 在线支付
const moneyAddFn = async () => {
  try {
    code_url.value = '';
    // 根据 payStatus.value 调用不同的 API
    const res = payStatus.value
      ? await addMoney({ fee: form.value.amout })
      : await alipayApi({ fee: form.value.amout });
    if (res.code == 20000) {
      code_url.value = res.data.code_url;
      out_trade_no.value = res.data.out_trade_no;
      // 设置过期时间为当前时间 + 5分钟 (300000毫秒)
      expireTime.value = Date.now() + 5 * 60 * 1000; // 修改这里
      // 开始轮询支付状态
      startPolling();
    }
  } catch (error) {
    console.log('error:', error);
  }
};

// 定义轮询状态的方法
const checkPaymentStatus = async () => {
  // if (showRefresh.value) {
  //   ElMessage.error('订单已过期，无法继续支付');
  //   stopPolling();
  //   return;
  // }
  try {
    const response = await payVerificationApi({
      out_trade_no: out_trade_no.value,
    });
    paymentStatus.value = response; // 假设返回的状态字段名为 status

    // 如果支付完成或其他条件达到，则停止轮询
    if (paymentStatus.value && paymentStatus.value.code == 20000) {
      ElMessage({
        message: paymentStatus.value.msg,
        type: 'success',
      });
      stopPolling();
      tableDataList();
      dialogTableVisible.value = false;
    } else {
      return;
    }
  } catch (error) {
    console.log('error:', error);
  }
};
// 启动轮询
const startPolling = () => {
  pollingInterval = setInterval(() => {
    checkPaymentStatus();
    const currentTime = Date.now();
    timeLeft.value = Math.max(0, expireTime.value - currentTime); // 计算剩余时间
  }, 1000); // 每1秒检查一次

  setTimeout(stopPolling, 300000); // 5分钟后停止轮询
};

// 停止轮询
const stopPolling = () => {
  clearInterval(pollingInterval);
  pollingInterval = null;
  showRefresh.value = true;
};
//代收钱包充值
const getCollection = async () => {
  try {
    const data = await collectionAPI({ money: form.value.amout });
    if (data.code == 20000) {
      ElMessage({
        message: data.msg,
        type: 'success',
      });
      getUserMoney();
      tableDataList();
    }
  } catch (err) {
    console.log(err);
  }
};

//提交表单
const submitForm = async (formEl) => {
  if (!formEl) return;
  showRefresh.value = false;
  await formEl.validate((valid) => {
    if (valid) {
      if (form.value.payType == 1) {
        nextTick(() => {
          moneyAddFn();
        });
        dialogTableVisible.value = true;
      } else if (form.value.payType == 2) {
        dialogTableVisible.value = true;
      } else {
        form.value.type ? form.value.type : '';
        getCollection();
      }
    }
  });
};
const addfee = () => {
  showRefresh.value = false;
  moneyAddFn();
};
// 页码
const currentChange = (val) => {
  loading.value = true;
  tableConfig.value.page = val;
  tableDataList();
};
const pagination = (val) => {
  loading.value = true;
  tableConfig.value.pageSize = val;
  tableDataList();
};
//或取时间
const getChangeTime = (val) => {
  loading.value = true;
  if (val) {
    tableConfig.value.startTime = formatDateYMD(new Date(val[0]));
    tableConfig.value.endTime = formatDateYMD(new Date(val[1]));
  } else {
    tableConfig.value.starTime = '';
    tableConfig.value.endTime = '';
  }
  tableDataList();
};
//充值类型
const rechageType = () => {
  const { page, pageSize } = tableConfig.value;
  merchantType({ page, pageSize }).then(({ data }) => {
    payList.value = data.data;
  });
};
// 复制到剪贴板功能
const copyToClipboard = (text) => {
  const textInfo = text.bank + ' ' + text.name + ' ' + text.root;
  navigator.clipboard
    .writeText(textInfo)
    .then(() => {
      ElMessage.success('复制成功');
    })
    .catch(() => {
      ElMessage.error('复制失败');
    });
};
//我已转账
const getpayApi = () => {
  const { type, amout } = form.value;

  commitRechargeApi({ type, amout }).then(({ data }) => {
    form.value.id = data.id;
    uploadCredentialsForm.value.RechargeMoney = data.RechargeMoney;
    uploadCredentialsForm.value.order = data.order;
  });
};
const tableDataList = () => {
  rechargeLog(tableConfig.value).then(({ data }) => {
    tableData.value = data.data;
    tableConfig.value.total = data.total;
    loading.value = false;
  });
};
//账户余额
const getUserMoney = async () => {
  try {
    const { data } = await accountBalanceApi();
    moneyNum.value = data.storeBalance;
    balance.value = data.balance;
  } catch (error) {
    console.log('error:', error);
  }
};

onMounted(() => {
  tableDataList();
  rechageType();
  getUserMoney();
});
</script>

<style lang="scss" scoped>
@import '@/assets/styles/global.scss';
:deep(.el-form-item__label) {
  font-weight: 400;
  color: #86909c;
}
// :deep(.el-radio:last-child) {
//   margin-right: 6px;
// }
:deep(.el-radio) {
  margin-right: 15px;
}
:deep(.el-radio__input.is-checked + .el-radio__label) {
  color: var(--primary-color);
}
:deep(.el-radio__input.is-checked .el-radio__inner) {
  background: var(--primary-color);
}
:deep(.el-upload) {
  width: 360px;
  height: 180px;
}
:deep(.el-dialog__body, .el-dialog__footer) {
  padding: 24px 24px 16px 24px;
}
:deep(.el-dialog__header) {
  height: 36px;
  min-height: 0;
}
:deep(.dialog-footer) {
  border: none !important;
}
.userMon {
  font-size: 14px;
  color: #86909c;
  font-weight: 400;
}
.count {
  text-align: center;
}
.refresh {
  cursor: pointer;
  color: blueviolet;
}
.model {
  width: 200px;
  height: 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: rgba(255, 255, 255, 0.8);
  position: absolute;
  top: 0;
  left: calc(50% - 100px);
  opacity: 0.5; /* 背景透明 */
}
.moneyNum {
  font-size: 14px;
  font-weight: 600;
  color: #1d2129;
}
.check {
  width: 1em;
  height: 1em;
  margin-right: 8px;
  position: absolute;
  right: -7px;
  bottom: 1px;
  color: #fff;
  font-weight: bold;
  z-index: 10;
}
.stylebtn {
  width: 170px;
  background-color: var(--primary-color);
  border-color: var(--primary-color);
  color: #fff;
  line-height: 40px;
}
.stylebtn:hover {
  opacity: 0.9;
}
.txt {
  font-weight: 400;
  color: var(--text-primary-color);
}
.text {
  color: var(--danger-color);
  display: inline-block;
  margin-right: 5px;
}
.moneyT {
  color: #4e5969;
  font-size: 14px;
}
.dialog-footer {
  display: flex;
  justify-content: center;
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid #ccc;
}
.cope {
  position: absolute;
  bottom: -10px;
  right: 40px;
  cursor: pointer;
  color: var(--primary-color);
}
.top {
  font-weight: 400;
  color: #666;
  text-align: center;
  padding-top: 24px;
}
.item {
  margin-bottom: 20px;
}
.info {
  position: relative;
  padding: 20px;
  margin-bottom: 20px;
  margin-top: 40px;
  width: 380px;
  background: rgb(247, 248, 250);
}
.pic {
  width: 20px;
  height: 20px;
  margin-right: 10px;
}
.money {
  color: var(--danger-color);
}
.isNone {
  display: none !important;
}
.payMoney {
  display: flex;
  justify-content: center;
  cursor: pointer;
  width: 164px;
  height: 52px;
  box-sizing: border-box;
  line-height: 52px;
  text-align: center;
  background: #fff;
  border-radius: 4px;
  border: 1px solid #dcdee0;
  align-items: center;
  margin-right: 10px;
  position: relative; /* 使伪元素定位相对于其父元素 */
}
.payChange {
  text-align: center;
  cursor: pointer;
  color: var(--primary-color);
}
.payChange:hover {
  color: var(--primary-color);
}
.wxPay {
  color: red;
  font-size: 12px;
}
.payMoney:hover {
  color: var(--primary-color);
}
.payMoney > .bg {
  // content: ''; /* 必须设置 content 属性 */
  position: absolute;
  right: -14px; /* 让三角形居中 */
  bottom: -4px; /* 放在父元素的上方 */
  width: 0;
  height: 0;

  border-left: 20px solid transparent; /* 左边透明边框 */
  border-right: 20px solid transparent; /* 右边透明边框 */
  border-bottom: 20px solid var(--primary-color); /* 底部蓝色边框，形成三角形 */
  transform: rotate(134deg);
}
.active {
  border: 1px solid var(--primary-color);
}
.icon {
  color: var(--primary-color);
  font-size: 20px;
  cursor: pointer;
}
.flexcenter {
  display: flex;
  flex-wrap: wrap;

  p {
    line-height: 22px;
    color: #4e5969;
    font-size: 14px;
    word-break: break-all;
    padding-top: 10px;
  }
}
.label {
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary-color);
  margin-right: 15px;
  line-height: 16px;
}
.item {
  display: flex;
  .value {
    font-size: 14px;
    font-weight: 400;
    color: #86909c;
    line-height: 16px;
  }
}
</style>
<style lang="scss">
// .maskBox {
//   .el-dialog {
//     max-height: none !important;
//   }
// }
</style>
